package com.mk.ancientrpcstarter.server;

import com.mk.ancientrpcstarter.logging.Log;
import com.mk.ancientrpcstarter.logging.LogFactory;
import com.mk.ancientrpcstarter.properties.AncientRpcServerConfig;
import com.mk.ancientrpcstarter.util.PkgDecoder;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

/**
 * @description:
 * @author: M.K
 * @date: 2021/12/18
 */

public class TcpServer {

    public static Log log = LogFactory.getLog(TcpServer.class);

    // Tcp 服务名称
    private String serverName;
    private AncientRpcServerConfig serverConfig;
    private final EventLoopGroup bossGroup;     // 处理Accept连接事件的线程
    private final EventLoopGroup workerGroup;   // 处理handler的工作线程

    public TcpServer(AncientRpcServerConfig serverConfig) {
        this.serverConfig = serverConfig;

        // IO线程 用于处理Acceptor事件
        this.bossGroup = new NioEventLoopGroup(1);
        int cores = Runtime.getRuntime().availableProcessors();
        // 工作线程
        this.workerGroup = new NioEventLoopGroup(cores);
    }

    public void start() throws Exception {
        try {
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(bossGroup, workerGroup);
            serverBootstrap.channel(NioServerSocketChannel.class);
            serverBootstrap.option(ChannelOption.SO_BACKLOG, 1024); //连接数
            serverBootstrap.localAddress(this.serverConfig.getPort());
            serverBootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);
            serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
                @Override
                protected void initChannel(SocketChannel socketChannel) throws Exception {
                    ChannelPipeline pipeline = socketChannel.pipeline();
                    pipeline.addLast(new PkgDecoder());
                    pipeline.addLast(new ServerHandler());
                }
            });

            ChannelFuture channelFuture = serverBootstrap.bind().sync();
            if (channelFuture.isSuccess()) {
                log.debug("rpc server start success!");
            } else {
                log.debug("rpc server start fail!");
            }
            channelFuture.channel().closeFuture().sync();
        } catch (Exception ex) {
            log.error("exception occurred exception=" + ex.getMessage());
        } finally {
            bossGroup.shutdownGracefully().sync();          // 释放线程池资源
            workerGroup.shutdownGracefully().sync();
        }
    }
}
